// Copyright 2010, Shuo Chen.  All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)

#ifndef MUDUO_BASE_WEAKCALLBACK_H
#define MUDUO_BASE_WEAKCALLBACK_H

#include <functional>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>

namespace muduo
{

	// A barely usable WeakCallback

#ifdef __GXX_EXPERIMENTAL_CXX0X__

// FIXME: support std::shared_ptr as well, maybe using template template parameters

	template<typename CLASS, typename... ARGS>
	class WeakCallback
	{
	public:

		WeakCallback(const boost::weak_ptr<CLASS>& object,
			const std::function<void(CLASS*, ARGS...)>& function)
			: object_(object), function_(function)
		{
		}

		// Default dtor, copy ctor and assignment are okay

		void operator()(ARGS&&... args) const
		{
			boost::shared_ptr<CLASS> ptr(object_.lock());
			if (ptr)
			{
				function_(ptr.get(), std::forward<ARGS>(args)...);
			}
			// else
			// {
			//   LOG_TRACE << "expired";
			// }
		}

	private:

		boost::weak_ptr<CLASS> object_;
		std::function<void(CLASS*, ARGS...)> function_;
	};

	template<typename CLASS, typename... ARGS>
	WeakCallback<CLASS, ARGS...> makeWeakCallback(const boost::shared_ptr<CLASS>& object,
		void (CLASS::*function)(ARGS...))
	{
		return WeakCallback<CLASS, ARGS...>(object, function);
	}

	template<typename CLASS, typename... ARGS>
	WeakCallback<CLASS, ARGS...> makeWeakCallback(const boost::shared_ptr<CLASS>& object,
		void (CLASS::*function)(ARGS...) const)
	{
		return WeakCallback<CLASS, ARGS...>(object, function);
	}

#else  // __GXX_EXPERIMENTAL_CXX0X__

// the C++98/03 version doesn't support arguments.

	template<typename CLASS>
	class WeakCallback // 弱回调？
	{
	public:

		WeakCallback(const boost::weak_ptr<CLASS>& object,
			const boost::function<void(CLASS*)>& function)
			: object_(object), function_(function)
		{
		}

		// Default dtor, copy ctor and assignment are okay

		void operator()() const // 重载了括号表达式
		{
			boost::shared_ptr<CLASS> ptr(object_.lock()); 
			if (ptr) // 如果指向的对象还存在的话
			{
				function_(ptr.get()); // 调用对应的函数
			}
			// else
			// {
			//   LOG_TRACE << "expired";
			// }
		}

	private:

		boost::weak_ptr<CLASS> object_; 
		boost::function<void(CLASS*)> function_; // 一个类似于函数指针的东西
	};

	template<typename CLASS>
	WeakCallback<CLASS> makeWeakCallback(const boost::shared_ptr<CLASS>& object,
		void (CLASS::*function)())
	{
		return WeakCallback<CLASS>(object, function); // 这是构建一个WeakCallback对象的节奏啊！
	}

	template<typename CLASS>
	WeakCallback<CLASS> makeWeakCallback(const boost::shared_ptr<CLASS>& object,
		void (CLASS::*function)() const)
	{
		return WeakCallback<CLASS>(object, function);
	}

#endif  // __GXX_EXPERIMENTAL_CXX0X__
}

#endif
